import xbmc
import xbmcgui
import os
import pickle
import socket
import fcntl
import struct
import xmlrpclib
import subprocess as subp

class SettingWindow(xbmcgui.Window):
	http_service = "http://localhost:9870"
	setting_home_dir = os.path.expanduser("~") + "/.qlive/setting/"

	# default constructor
	def __init__(self):
		self.settings = {}
		self.selected_if = ""
		self.setting_file = self.setting_home_dir + "Qlive_Setting.bin"

		self.loadSetting()
		self.initComponent()
		self.setCoordinateResolution(1)

	# load previous setting from file
	def loadSetting(self):
		if os.path.exists(self.setting_file) :
			f = open(self.setting_file, "rb")
			up = pickle.Unpickler(f)
			self.settings = up.load()
			f.close()
		else :
			self.settings["DEFAULT_GW"] = "192.168.1.1"
			self.settings["CONFERENCE_IP"] = "0.0.0.0"

	# get current address
	def getIpAddress(self, ifname):
		s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
		return socket.inet_ntoa(fcntl.ioctl(
			s.fileno(),
			0x8915,
			struct.pack('256s', ifname[:15])
		)[20:24])

	# get current mask
	def getNetmask(self, ifname):
		command = "ifconfig -a %s | grep Mask | awk '{ print substr($4,6) }'" % (ifname)
		proc = subp.Popen([command],shell=True, stdout=subp.PIPE)
		proc.wait()
		netmask = proc.stdout.readline().strip()
		return netmask

	# get current default gateway
	def getDefaultGateway(self):
		command = "ip route show default | awk '/default/ { print $3}'"
		proc = subp.Popen(command, shell=True, stdout=subp.PIPE)
		proc.wait()
		default_gateway = proc.stdout.readline().strip()
		return default_gateway

	# get interface list (only wlan and eth)
	def getIfList(self):
		command = """ifconfig -a | grep "Link encap" | awk '{print $1}'"""
		proc = subp.Popen(command, shell=True, stdout=subp.PIPE)
		proc.wait()
		if_names = proc.stdout.readlines()
		return [x.strip() for x in if_names if x.startswith("eth") or x.startswith("wlan")]

	# create setting component
	def initComponent(self):
		
		## Interface
		###########################################
		self.createImage(300,50,700,30, "background.gif")
		self.createLabel(100,55, "Interface")
		self.if_list = self.createList(300,50,700,50)

		## Focus
		###########################################
		self.setFocus(self.if_list)
		
		if_names = self.getIfList()
		for name in if_names :
			if_info = { "ADDRESS" : "", "MASK" : "", "STATUS" : "" }
			self.settings[name] = if_info
			self.createItem(name,name, self.if_list)
	
		## Propertie
		###############################################
		self.createImage(300,100,700,120, "background.gif")
		self.createLabel(100,105, "Properties")
		self.properties_list = self.createList(300,100,700,120)

		## Global
		##############################################
		gateway = self.getDefaultGateway()
		conference_ip = self.settings["CONFERENCE_IP"]

		self.createImage(300,300,700,80, "background.gif")
		self.createLabel(100,305, "")

		self.global_list = self.createList(300,305,700,80)
		self.gtw_item = self.createItem("Default Gateway", gateway , self.global_list)
		self.con_serv_item = self.createItem("Conference Server", conference_ip , self.global_list)

		## Device
		##############################################	
		self.createImage(300,400,700,200, "background.gif")
		self.createLabel(100,405, "Device")

		self.device_list = self.createList(300,400,700,200)
		self.sound_item = self.createItem("Sound Device", "Plantronics", self.device_list)
		self.video_item = self.createItem("Video Device", "Logitech", self.device_list)

		## On Control
		##############################################
		self.if_list.controlRight(self.properties_list)
		self.properties_list.controlRight(self.global_list)
		self.global_list.controlRight(self.device_list)

		self.device_list.controlLeft(self.global_list)
		self.global_list.controlLeft(self.properties_list)
		self.properties_list.controlLeft(self.if_list)

	# get interface properties  
	def getIfProperties(self, if_name):
		script_file = self.setting_home_dir + "Util_InterfaceInfo.sh"
		command = "bash %s %s" % (script_file, if_name)
		proc = subp.Popen(command, shell=True, stdout=subp.PIPE,stderr=subp.PIPE)
		proc.wait()

		info = proc.stdout.readline().strip().split(" ")
		error = proc.stderr.readline().strip().split(" ")
		print info
		print error

		ifname, address, mask, status = info
		return address, mask, status

	# show interface's properties
	def showProperties(self, if_name):
		self.properties_list.reset()

		address, mask, status = self.getIfProperties(if_name)
		
		self.ip_item = self.createItem("Address", address, self.properties_list)
		self.mask_item = self.createItem("Netmask", mask, self.properties_list)
		self.status_item = self.createItem("Status", status, self.properties_list)

		self.settings[if_name]["ADDRESS"] = address
		self.settings[if_name]["MASK"] = mask
		self.settings[if_name]["STATUS"] = status

	# create & add ControlList
	def createList(self,x,y,w,h):
		back = os.getcwd() + "/" + "h2.png"
		list = xbmcgui.ControlList(x,y,w,h, buttonFocusTexture= back)
		self.addControl(list)
		return list

	# create & add ControlLabel
	def createLabel(self, x,y, text):
		label = xbmcgui.ControlLabel(x,y,200,20, text)
		self.addControl(label)

	# create & add ListItem
	def createItem(self,title, value,listt):
		item = xbmcgui.ListItem()
		item.setLabel(title)
		item.setLabel2(value)
		listt.addItem(item)
		return item

	# create & add ControlImage
	def createImage(self, x,y ,w ,h, image):
		image = xbmcgui.ControlImage(x,y,w,h, os.getcwd() + "/" +image)
		self.addControl(image)

	# on control event handler (key Enter)
	def onControl(self, control):
		if control == self.if_list :
			selected_item = control.getSelectedItem()
			if_name = selected_item.getLabel()
			self.selected_if = if_name
			self.showProperties(if_name)

		elif control == self.properties_list :
			kb = xbmc.Keyboard()
			print "qlive > control list"
			selected_item = control.getSelectedItem()
			if selected_item == self.ip_item :
				kb.setHeading("Set ip address")
				kb.doModal()
				if(kb.isConfirmed()):
					new_ip = kb.getText()
					self.settings[self.selected_if]["ADDRESS"] = new_ip
					selected_item.setLabel2(new_ip)

			elif selected_item == self.mask_item :
				kb.setHeading("Set netmask")
				kb.doModal()
				if(kb.isConfirmed()):
					new_mask = kb.getText()
					self.settings[self.selected_if]["MASK"] = new_mask
					selected_item.setLabel2(new_mask)

			elif selected_item == self.status_item :
				status = selected_item.getLabel2()
				if status == "up" :
					self.settings[self.selected_if]["STATUS"] = "down"
					selected_item.setLabel2("down")
				else :
					self.settings[self.selected_if]["STATUS"] = "up"
					selected_item.setLabel2("up")

		# global list
		elif control == self.global_list :
			print "qlive > global_list ..."

			kb = xbmc.Keyboard()
			selected_item = control.getSelectedItem()

			if selected_item == self.con_serv_item :
				kb.setHeading("Set Conference Server")
				kb.doModal()
				if(kb.isConfirmed()):
					new_serv = kb.getText()
					self.settings["CONFERENCE_IP"] = new_serv
					selected_item.setLabel2(new_serv)
			elif selected_item == self.gtw_item :
				kb.setHeading("Set Default Gateway")
				kb.doModal()
				if(kb.isConfirmed()):
					new_gtw = kb.getText()
					self.settings["DEFAULT_GW"] = new_gtw
					selected_item.setLabel2(new_gtw)

		# device list
		elif control == self.device_list :
			print "alive > device list"
			selected_item = control.getSelectedItem()
			if selected_item == self.sound_item :
					print "qlive > test sound .."
					command = "aplay %squestion.wav" % (self.setting_home_dir)
					os.system(command)

	# active new configuration for current env
	def updateConfig(self):
		script_loc = os.path.expanduser("~") + "/.qlive/setting/Util_ChangeIP.sh"
		proxy = xmlrpclib.ServerProxy(self.http_service)

		for name in self.getIfList() :
			info = self.settings[name]
			address = info["ADDRESS"]
			mask = info["MASK"]

			"""
			command = ["bash", script_loc, name ,mask ]
			p = subp.Popen(command, shell=False, stdout=subp.PIPE, stderr=subp.PIPE)
			p.wait()

			print "qlive > command = " + str(command)
			print "qlive > OUTPUT --------------------------"
			print p.stdout.readlines()

			print "qlive > ERROR ---------------------------"
			print p.stderr.readlines()
			"""
			proxy.updateAddress(name, address, mask)

		proxy.updateDefaultGateway(self.settings["DEFAULT_GW"])

		print "qlive > updated config"


	# save current setting
	def saveSetting(self):
		conference_ip = self.settings["CONFERENCE_IP"] 
		os.system("""perl -p -i -e "s/(^.+?)\s/%s /g" $HOME/.qlive/conference/Auth_DataBase.qlive """ % conference_ip)
		f = open(self.setting_file, "w")
		pk = pickle.Pickler(f)
		pk.dump(self.settings)
		f.close()

	# on action event handler (any key)
	def onAction(self, action):
		if action == 10 : # esc key
			self.close()
			self.saveSetting()
			self.updateConfig()

## main section, start here
#############################
if __name__ == "__main__" :
	s = SettingWindow()
	s.doModal()
